package com.gmrz.uaf.remote.plugin;

import com.gmrz.uaf.common.Constants;
import com.gmrz.uaf.common.GuiceUtil;
import com.gmrz.uaf.db.DAOFactory;
import com.gmrz.uaf.db.UAFDAOFactory;
import com.gmrz.uaf.db.UAFDBConnectionMgr;
import com.gmrz.uaf.db.dao.PluginDataDAO;
import com.gmrz.uaf.server.ServerConfig;
import com.gmrz.uas.plugin.authservice.AuthServiceConfigSpec;
import com.gmrz.uas.plugin.authservice.AuthServiceData;
import com.gmrz.uas.plugin.authservice.AuthServiceDataSpec;
import com.gmrz.uas.plugin.authservice.AuthServicePlugin;
import com.gmrz.uas.plugin.authservice.exception.InvalidConfigException;
import com.gmrz.uas.plugin.exception.PluginException;
import com.gmrz.uas.plugin.provider.ServiceProvider;
import com.gmrz.util.Convert;
import com.gmrz.util.db.DBUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

/**
 * Created by gongyuqiang on 2017/5/23.
 */
public class AuthServicePluginAdapter implements AuthServicePlugin {
    private static final Logger LOG = LogManager.getLogger(AuthServicePluginAdapter.class);
    private AuthServicePlugin  adapter= null;
    private String aaid = null;
    private String authType = null;

    AuthServicePluginAdapter(String aaid, String authType, AuthServicePlugin adapter){
        this.aaid = aaid;
        this.authType = authType;
        this.adapter = adapter;
    }

    protected void saveData(List<AuthServiceData> contents, int operType){
        //TODO 数据库操作
        Connection conn = null;
        try {
            LOG.debug("begin to saveData ");
            Map<String, AuthServiceDataSpec> specs = this.adapter.getAllDataSpec();
            if(specs != null && specs.size() != 0){
                int index = 0;
                PluginData data = new PluginData();
                data.setAaid(this.aaid);
                data.setAuthType(this.authType);
                data.setOperType(operType);
                for(AuthServiceData content: contents){
                    if(specs.containsKey(content.getId())){
                        AuthServiceDataSpec spec = specs.get(content.getId());
                        if(spec.isSupportPersistent()){
                            LOG.debug( content.getId() + "will to save to database");
                            data.setData(index++, Convert.toBase64String(content.getContent()));
                        }
                    }
                }
                if(data.getDataCount() > 0){
                    LOG.debug("insert plugin data to database");
                    conn = UAFDBConnectionMgr.getLogConnection(false);
//                    PluginDataDAO dao = GuiceUtil.getProcessorInjector().getInstance(DAOFactory.class).createPluginDataDAO(conn);
                    PluginDataDAO dao = UAFDAOFactory.createPluginDataDAO(conn);
                    dao.insert(data);
                    conn.commit();
                }
            }

        }catch (SQLException sqle){
            LOG.error(sqle);
            LOG.error("DataBase connection error while saving plugin data",sqle);
        }catch (Exception e){
            e.printStackTrace();
            LOG.error(e);
            LOG.error("Unknown error while saving FIDO plugin data",e);
        }finally {
            DBUtil.close(conn);
        }
        LOG.info("end to savedata");
    }
    @Override
    public String getPluginId() {
        return this.adapter.getPluginId();
    }

    @Override
    public void setServiceProvider(ServiceProvider provider) {
        this.adapter.setServiceProvider(provider);
    }

    @Override
    public Map<String, AuthServiceConfigSpec> getAllConfigSpec() {
        return this.adapter.getAllConfigSpec();
    }

    @Override
    public Map<String, AuthServiceDataSpec> getAllDataSpec() {
        return this.adapter.getAllDataSpec();
    }

    @Override
    public Map<String, String> getAllConfig() {
        return this.adapter.getAllConfig();
    }

    @Override
    public void setAllConfig(Map<String, String> allConfig) throws InvalidConfigException {
        this.adapter.setAllConfig(allConfig);
    }

    @Override
    public List<AuthServiceData> pregregister(String userId) throws PluginException {
        return this.adapter.pregregister(userId);
    }

    @Override
    public void register(String userId, List<AuthServiceData> contents) throws PluginException {
        try{
            this.adapter.register(userId, contents);
        }
        finally {
            ServerConfig serverConfig = GuiceUtil.getProcessorInjector().getInstance(ServerConfig.class);
            if(serverConfig.isPluginPersistent()){
                saveData(contents, Constants.Method.REG_FINISH.getOperType());
            }
        }

    }

    @Override
    public void unregister(String userId) throws PluginException {
        this.adapter.unregister(userId);
    }

    @Override
    public List<AuthServiceData> preauthenticate(String userId) throws PluginException {
        return this.adapter.preauthenticate(userId);
    }

    @Override
    public void authenticate(String userId, List<AuthServiceData> contents) throws PluginException {
        try {
            this.adapter.authenticate(userId, contents);
        }
        finally {
            ServerConfig serverConfig = GuiceUtil.getProcessorInjector().getInstance(ServerConfig.class);
            if(serverConfig.isPluginPersistent()){
                saveData(contents, Constants.Method.AUTH_FINISH.getOperType());
            }

        }
    }
}
